<?php
namespace WDB\Query\Element;
use WDB,
    WDB\Exception;
/**
 * Database function element.
 * 
 * WDB supports two type of function elements. See constructor argument "custom" documentation for details.
 * While normal DBFunction object represent a function on WDB level, which is translated to a
 * platform-dependent function, custom function means a platform-native function, which is converted
 * directly to SQL with specified name and arguments.
 * WDB function support may slightly vary over database drivers, but there is a list of functions
 * generally supported:
 * CURRENT_SCHEMA()
 * COUNT([column_name])
 * VALUES(c)
 *
 * @author Richard Ejem <richard(at)ejem.cz>
 * @package WDB
 */
final class DBFunction extends WDB\BaseObject implements iExpression
{   
    /**@var string*/
    private $name;
    /**@var iElement[]*/
    private $args;
    /**@var bool*/
    private $custom;
    
    /**
     * Factory - current schema function
     *
     * @return DBFunction
     */
    public static function currentSchema()
    {
        return new DBFunction('CURRENT_SCHEMA');
    }
    
    /**
     * Factory - VALUES(c) function for mysql ON DUPLICATE KEY UPDATE clause (emulated on other databases)
     * 
     * @param string column name
     * @return DBFunction 
     */
    public static function Values($column)
    {
        if (!$column instanceof iExpression)
        {
            $column = new ColumnIdentifier(array('column'=>$column));
        }
        return new DBFunction('VALUES', array($column));
    }
    
    /**
     * Factory- count of records of specified columns
     * 
     * @param ColumnIdentifier|string column
     * @return DBFunction 
     * @throws Exception\BadArgument
     */
    public static function countRows($column = NULL)
    {
        if ($column === NULL)
        {
            $column = ColumnIdentifier::allColumns();
        }
        else
        {
            if (!$column instanceof ColumnIdentifier)
            {
                if (is_string($column))
                {
                    $column = new ColumnIdentifier(array('column'=>$column));
                }
                else
                {
                    throw new Exception\BadArgument();
                }
            }
        }
        return new DBFunction('COUNT', array($column));
    }
    
    /**
     *
     * @param string function name
     * @param iExpression[] arguments
     * @param bool custom - keeping it false means that function name is under WDB
     * standard and may be translated to different function name by the database driver.
     * Setting to true tells the driver to use exactly this function name.
     * It is because there are too many database functions so there are few commons
     * translated by the driver for maximum compatibility, but custom function name
     * grants an easy way to use database-specific or less common functions.
     */
    public function __construct($f, $args = array(), $custom = FALSE)
    {
        $this->custom = $custom;
        $this->args = $args;
        $this->name = $f;
    }

    public function toSQL(\WDB\SQLDriver\iSQLDriver $driver)
    {
        return $driver->tosql_function($this->name, $this->args, $this->custom);
    }
}
